package javax.generic.persistance;

import java.util.List;

/**
 * Generic data access object that provides commonly used methods for a single
 * entity.
 * 
 * @author mdinic
 * @param <T> type of persisted entity this DAO will handle
 */
public interface GenericDao {

	/**
	 * Saves provided entity to database.
	 * 
	 * @param entity
	 */
	void persist(AbstractPersistableEntity entity);

	/**
	 * Updates properties in database for provided entity.
	 * 
	 * @param entity
	 * @return
	 */
	AbstractPersistableEntity update(final AbstractPersistableEntity entity);

	/**
	 * Fetches entity for provided id. NOTE: throws an exception if entity is
	 * not found!
	 * 
	 * @param id id of the entity
	 * @return
	 */
	Object loadById(long id, Class<? extends AbstractPersistableEntity> persistentClass);

	/**
	 * Fetches a list of all entities.
	 * 
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	List findAll(Class<? extends AbstractPersistableEntity> persistentClass);

	/**
	 * Count all entities.
	 * 
	 * @return number of entities
	 */
	int count(Class<? extends AbstractPersistableEntity> persistentClass);

	/**
	 * Fetches a list of entities by range (paging like).
	 * 
	 * @param first index of first element
	 * @param count number of elements to fetch
	 * @return list of entities
	 */
	List<? extends AbstractPersistableEntity> findByRange(int first, int count, Class<? extends AbstractPersistableEntity> persistentClass);

	/**
	 * Removes the entity instance.
	 * 
	 * @param entity
	 */
	void remove(AbstractPersistableEntity entity, Class<? extends AbstractPersistableEntity> persistentClass);

	/**
	 * Removes the list of entity instances.
	 * 
	 * @param entities
	 */
	void removeAll(List<? extends AbstractPersistableEntity> entities, Class<? extends AbstractPersistableEntity> persistentClass);

	void refresh(AbstractPersistableEntity entity);

	void removeById(Long id, Class<? extends AbstractPersistableEntity> persistentClass);

	@SuppressWarnings("rawtypes")
	List search(AbstractPersistableEntity object, Class<? extends AbstractPersistableEntity> persistentClass);

	@SuppressWarnings("rawtypes")
	List searchExact(AbstractPersistableEntity object, Class<? extends AbstractPersistableEntity> persistentClass);

	List findByCriteria(Object value, String criteriaName, Class<? extends AbstractPersistableEntity> persistentClass);

}
